﻿using System;
using System.Collections.Generic;

namespace _13_ChainOfResponsibility
{
    class Program
    {
        //责任链是一种行为设计模式， 允许你将请求沿着处理者链进行发送， 直至其中一个处理者对其进行处理。
        static void Main(string[] args)
        {
            var monkey = new MonkeyHandler();
            var squirrel = new SquirrelHandler();
            var dog = new DogHandler();
            monkey.SetNext(squirrel).SetNext(dog);

            Console.WriteLine("Chain:monkey > Squirrel > Dog\n");
            Client.ClientCode(monkey);
            Console.WriteLine();
            Console.WriteLine("Subchain:Squirrel > Dog\n");
            Client.ClientCode(squirrel);
            Console.ReadKey();
        }
    }
    public interface IHandler
    {
        IHandler SetNext(IHandler handler);
        Object Handle(object request);
    }
    abstract class AbstractHandler : IHandler
    {
        private IHandler _nextHandler;
        public IHandler SetNext(IHandler handler)
        {
            _nextHandler = handler;
            return handler;
        }
        public virtual object Handle(object request)
        {
            if (_nextHandler != null)
            {
                return _nextHandler.Handle(request);
            }
            else
            {
                return null;
            }
        }
    }
    class MonkeyHandler : AbstractHandler
    {
        public override object Handle(object request)
        {
            if ((request as string) == "Banana")
            {
                return $"Monkey: I'll eat the {request.ToString()}.\n";
            }
            else
            {
                return base.Handle(request);
            }
        }
    }
    class SquirrelHandler : AbstractHandler
    {
        public override object Handle(object request)
        {
            if (request.ToString() == "Nut")
            {
                return $"Squirrel: I'll eat the {request.ToString()}.\n";
            }
            else{
                return base.Handle(request);
            }
        }
    }
    class DogHandler : AbstractHandler
    {
        public override object Handle(object request)
        {
            if (request.ToString() == "MeatBall")
            {
                return $"Dog: I'll eat the {request.ToString()}.\n";
            }
            else
            {
                return base.Handle(request);
            }
        }
    }
    class Client
    {
        public static void ClientCode(AbstractHandler handler)
        {
            foreach (var food in new List<string> { "Nut","Banana","Cup of coffee"})
            {
                Console.WriteLine($"Client:Who wants a {food}?");
                var result = handler.Handle(food);
                if (result != null)
                {
                    Console.WriteLine($"{result}");
                }
                else
                {
                    Console.WriteLine($"{food} was left untouched.");
                }
            }

        }
    }
}
